home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
raytrace
/
pov
/
gen
/
dna09
/
dna_v090.cpp
next >
Wrap
C/C++ Source or Header
|
1993-12-30
|
12KB
|
289 lines
/*****************************************************************************
Program : DNA.EXE v0.90
Purpose : Creates twisted ladder-shaped objects ( like DNA strands ) for the
POV-Ray v2.x raytracer.
Created : 12/30/93
By : Rob Bryerton CIS [73747,433]
File : DNA_v090.CPP
Compiler: Microsoft C++ v8.00
Model : Medium
Comments: To do... add graphic preview, PolyRay and CTDS output
*****************************************************************************/
#include <fstream.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
const char cVERSION[6] = "v0.90";
void ErrExit(char *cMessage);
void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight,
double *dRadius, double *dPartRadius,
long *lStepsPerRevolution, long *lTotalSteps,
long *lConnectXsteps);
void ShowTitle();
inline void WriteCone(double dLastX, double dLastY, double dLastZ,
double dX, double dY, double dZ,
double dRad, ofstream& outfile, long *lGlobalCounter);
void WriteFileEnd(ofstream& outfile, long lGlobalCounter);
void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile,
double dHeight);
void WriteSceneFile(char *cFileName, char *cUnionName,
double dHeight, double dRadius);
inline void WriteSphere(double dX, double dY, double dZ, double dRad,
ofstream& outfile, long *lGlobalCounter);
int main()
{
char cFileName[80] = "DNA.INC";
char cUnionName[80] = "DNA";
double dRadius; // the radius of the twister (DNA strand)
double dHeight; // the overall length of the object
double dAngle; // used to calc the polar coordinates
double dPartRadius;// the radius of the spheres (and cones) written at each coordinate
double dLastXpos1, dLastZpos1, dLastYpos; // stores the previous values... used
double dLastXpos2, dLastZpos2; // to connect the cones together
long lTotalSteps;// the TOTAL number of coords calc'd
long lStepsPerRevolution;
long lGlobalCounter = 0; // the overall # of objects written to file
long lConnectorCounter = 0; // ready for another connector??
long lConnectXsteps; // connect strands every X steps
const double dPI = 3.1415926535897932384626;// hmmm
ofstream outfile; // the disk output file
ShowTitle();
/* get some user input and check for validity */
GetAndValidateUserInput(cFileName, cUnionName, &dHeight,
&dRadius, &dPartRadius,
&lStepsPerRevolution, &lTotalSteps,
&lConnectXsteps);
/* Open file for output */
cout<< "\nCreating data file " << cFileName << endl;
outfile.open(cFileName,ios::out); // try to open a disk file
if(! outfile) ErrExit("opening file."); // can't open disk file,exit
outfile.setf(ios::showpoint | ios::fixed); // successful, set formats
WriteFileHeader(cFileName, cUnionName, outfile, dHeight);
/* caculate each vector and write to file */
for(long lCurrentStep = 0; lCurrentStep < lTotalSteps; ++lCurrentStep)
{
dAngle = dPI * 2 * ( (double)lCurrentStep / (double)lStepsPerRevolution );
double dXpos1 = dRadius * cos(dAngle);
double dZpos1 = dRadius * sin(dAngle);
double dXpos2 = fabs(dRadius) * cos(dAngle);
double dZpos2 = fabs(dRadius) * sin(dAngle);
double dYpos = dHeight * ( (double)lCurrentStep / (double)lTotalSteps );
WriteSphere(dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
WriteSphere(dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
if(lCurrentStep > 0) // ignore this clause the first time around
{
WriteCone(dLastXpos1, dLastYpos, dLastZpos1, dXpos1, dYpos, dZpos1, dPartRadius, outfile, &lGlobalCounter);
WriteCone(dLastXpos2, dLastYpos, dLastZpos2, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
}
lConnectorCounter++;
if(lConnectorCounter == lConnectXsteps) /* write a connector? */
{
WriteCone(dXpos1, dYpos, dZpos1, dXpos2, dYpos, dZpos2, dPartRadius, outfile, &lGlobalCounter);
lConnectorCounter = 0; // reset counter to calc the next connector
}
dLastXpos1 = dXpos1; // now store x, y etc in Lastx, LastY etc
dLastZpos1 = dZpos1; // so we can use them on the next loop to
dLastXpos2 = dXpos2; // connect the cones and spheres together
dLastZpos2 = dZpos2;
dLastYpos = dYpos;
}
cout << lGlobalCounter << " objects written to " << cFileName << endl;
WriteFileEnd(outfile, lGlobalCounter);
outfile.close(); // close the output file
WriteSceneFile(cFileName, cUnionName, dHeight, dRadius); // now write a scene file
return(0);
}
/************************** FUNCTION DEFINITIONS *****************************/
void ErrExit(char *cMessage)
{
cerr << "\a\n\nERROR" << cMessage << "- Exiting \n";
exit(1);
}
void GetAndValidateUserInput(char *cFileName, char *cUnionName, double *dHeight,
double *dRadius, double *dPartRadius,
long *lStepsPerRevolution, long *lTotalSteps,
long *lConnectXsteps)
{
char cBuffer[256]; // general use (user input) buffer
const int iBUFFSIZECHAR = 80;// constant size for cin.getline() for character op's
const int iBUFFSIZENUMB = 80;// constant size for cin.getline() for numeric op's
cout << "\nOutput file name [DNA.INC]:";
cin.getline(cBuffer,iBUFFSIZECHAR);
if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA.INC");
cFileName = _strupr(cBuffer); // place capitalized contents of buffer in cFileName
/*************** VERIFY FILENAME *****************/
for(int i = 0; i < (int)strlen(cFileName); i++)
if (cFileName[i] == '.') break;
cFileName[i] = '.';
strcpy (&cFileName[i+1], "INC");
/*************************************************/
cout << "Union name [DNA]:";
cin.getline(cBuffer,iBUFFSIZECHAR);
if(cBuffer[0] == NULL) strcpy(cBuffer, "DNA");
strcpy(cUnionName, cBuffer);
cout << "Height (Y units) of object [50.0]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*dHeight = atof(cBuffer);
if( *dHeight <= 0.0 ) *dHeight = 50.0;
cout << "Radius (X-Z) of object [10.0]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*dRadius = atof(cBuffer);
if( *dRadius <= 0.0 ) *dRadius = 10.0;
*dRadius -= (*dRadius * 2); // to make the result a negative
cout << "Radius of individual objects [0.5]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*dPartRadius = atof(cBuffer);
if(*dPartRadius <= 0.0 ) *dPartRadius = 0.5;
cout << "Steps per revolution [30]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*lStepsPerRevolution = atoi(cBuffer);
if(*lStepsPerRevolution <= 0 ) *lStepsPerRevolution = 30;
cout << "Connect strands every X steps [3]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*lConnectXsteps = atoi(cBuffer);
if(*lConnectXsteps <= 0 ) *lConnectXsteps = 3;
cout << "Number of revolutions [1]:";
cin.getline(cBuffer,iBUFFSIZENUMB);
*lTotalSteps = atoi(cBuffer);
if(*lTotalSteps <=0) *lTotalSteps = 1;
*lTotalSteps = (*lTotalSteps * *lStepsPerRevolution);
// That * operator sure gets around!
}
void ShowTitle()
{
cout << "\nDNA "<< cVERSION << ", Copyright (c) 1993 Rob Bryerton\n"
<< "Creates a data file of a twisted ladder-shaped object\n"
<< "(like a DNA strand) for the POV-Ray v2.x raytracer.\n";
}
inline void WriteCone(double dLastX, double dLastY, double dLastZ,
double dX, double dY, double dZ,
double dRad, ofstream& outfile, long *lGlobalCounter)
{
outfile << "\n cone{ < " <<dLastX<< ", " << dLastY << ", " <<dLastZ<< " >, " << dRad << ", < " <<dX<< ", " << dY << ", " <<dZ<< " >, " << dRad << " }";
++*lGlobalCounter; //increment counter; note that postfix notation will not work
}
void WriteFileEnd(ofstream& outfile, long lGlobalCounter)
{
outfile << "\n}\n"
<< "\n// " << lGlobalCounter << " objects written to this file.\n";
}
void WriteFileHeader(char *cFileName, char *cUnionName, ofstream& outfile, double dHeight)
{
outfile << "// This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
<< "// File Name: " << cFileName << " Union Name: " << cUnionName << endl
<< "\n#declare " << cUnionName << " =\n"
<< "union {";
}
void WriteSceneFile(char *cFileName, char *cUnionName,
double dHeight, double dRadius)
{
struct Vector{ double x,y,z;};
char cSceneFileName[80];
ofstream sceneOutFile;
Vector CamLocation, CamLookAt, LightLocation;
/****************************************/
strcpy(cSceneFileName, cFileName);
for(int i = 0; i < (int)strlen(cSceneFileName); i++)
if (cSceneFileName[i] == '.') break; // create a SCENE filename based
// on the include filename
cSceneFileName[i] = '.'; // but with the ".POV" extension
strcpy (&cSceneFileName[i+1], "POV");
/****************************************/
cout<< "Creating scene file " << cSceneFileName << endl;
// calculate camera and light vectors based on object size
CamLocation.x = 0;
CamLocation.y = dHeight * 0.5;
CamLocation.z = dHeight - (dHeight * 2.2);
CamLookAt.x = 0;
CamLookAt.y = dHeight * 0.5;
CamLookAt.z = 0;
LightLocation.x = fabs(dRadius);
LightLocation.y = dHeight * 0.75;
LightLocation.z = dHeight - (dHeight * 2.0);
// open a disk file and write the scene file
sceneOutFile.open(cSceneFileName,ios::out); // try to open a disk file
if(! sceneOutFile) ErrExit("opening file."); // can't open disk file,exit
sceneOutFile.setf(ios::showpoint | ios::fixed);
sceneOutFile << "// This data file created by DNA.EXE " << cVERSION << " for the POV-Ray v2.x raytracer.\n"
<< "// Scene File: " << cSceneFileName << " Include File: " << cFileName << " Union Name: " << cUnionName << endl
<< "#include \"colors.inc\"\n"
<< "#include \"textures.inc\"\n\n";
sceneOutFile << "camera {\n"
<< " location < " << CamLocation.x << ", " << CamLocation.y << ", " << CamLocation.z << " >\n"
<< " look_at < " << CamLookAt.x << ", " << CamLookAt.y << ", " << CamLookAt.z << " >\n"
<< "}\n\n";
sceneOutFile << "light_source { < " << LightLocation.x << ", " << LightLocation.y << ", " << LightLocation.z << " > color White }\n"
<< "\n#declare " << cUnionName << "_Texture ="
<< "\ntexture { Y_Gradient finish { ambient 0.2 } scale<1," << dHeight << ",1> }\n\n";
sceneOutFile << "#include \"" << cFileName << "\"\n\n"
<< "object{"
<< "\n " << cUnionName
<< "\n texture{ " << cUnionName << "_Texture rotate < 0,0,25 > }"
<< "\n}\n";
sceneOutFile.close();
}
inline void WriteSphere(double dX, double dY, double dZ, double dRad,
ofstream& outfile, long *lGlobalCounter)
{
outfile << "\n sphere{ < " << dX << ", " << dY << ", " << dZ << " > " << dRad << " }";
++*lGlobalCounter;//increment counter; note that postfix notation will not work
}